package com.jy.modules.cims.component.credit.creditor.transferee;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.JResult;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.DateTimeUtils;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.common.sysUtils.SimpleBeanUtils;
import com.jy.modules.cims.component.common.CreditPackage;
import com.jy.modules.cims.component.common.service.TCMmCooperorgDealService;
import com.jy.modules.cims.component.common.service.TCMmCreditPackageService;
import com.jy.modules.cims.component.common.service.TCMmCustinfoService;
import com.jy.modules.cims.component.creditRight.ICCreditRight;
import com.jy.modules.cims.component.quota.CQuotaImpl;
import com.jy.modules.cims.component.sysAssist.CSysAssistImpl;
import com.jy.modules.cims.data.common.dto.TCMmCooperorgDealDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditDealDetailDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditDetailDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditPackageDTO;
import com.jy.modules.cims.data.common.dto.TCMmCustinfoDTO;
import com.jy.modules.cims.data.dao.CreditRightDao;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.CustomerDto;
import com.jy.modules.cims.data.dto.DealDto;
import com.jy.modules.cims.data.dto.credit.CreditApplyDto;
import com.jy.modules.cims.data.dto.credit.CreditApplyResultDto;
import com.jy.modules.cims.interact.CIRBaseDataSysImpl;
import com.jy.platform.api.org.SessionAPI;
import com.jy.platform.api.org.UserInfo;
import com.jy.platform.core.common.BaseDTO;

/**
 * @description 债权受让数据库操作层。
 * @author shengzhoutao
 * @date 2015-07-07
 */
@Service("com.jy.modules.cims.component.credit.creditor.transferee.TransgereeDao")
public class TransgereeDao {
	private final String STATUS_SUCCESS = "10000";// 返回状态成功：10000
	private final String STATUS_NONENTITY = "10001";// 返回状态不存在或已删除：10001
	private final String SYS_CODE_CIMS = "S004";//
	private final String CUST_CODE_KEY_NAME = "custCode";

	@Autowired
	private SessionAPI sessionAPI;

	@Autowired
	private CreditRightDao creditRightDao;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCooperorgDealService")
	private TCMmCooperorgDealService cooperorgDealService;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.CreditPackage")
	private CreditPackage creditPackage;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.creditRight.CCreditRightImpl")
	private ICCreditRight creditRight;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.sysAssist.CSysAssistImpl")
	private CSysAssistImpl csysAssistimpl;

	@Autowired
	@Qualifier("com.jy.modules.cims.interact.CIRBaseDataSysImpl")
	private CIRBaseDataSysImpl cIRBaseDataSysImpl;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCustinfoService")
	public TCMmCustinfoService tCMmCustinfoService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditPackageService")
	private TCMmCreditPackageService creditPackageService;

	/**
	 * @description 创建请求
	 * @param applyDto
	 * @throws Exception
	 * @author shengzhoutao
	 * @date 2015-07-07
	 */
	public void createApply(CreditApplyDto applyDto) throws Exception {

		// 新增合作机构流水
		TCMmCooperorgDealDTO cooperorgDealDTO = new TCMmCooperorgDealDTO();
		cooperorgDealDTO.setDealCode(applyDto.getDealCode());// 交易流水号
		cooperorgDealDTO.setContractCode(applyDto.getContractCode());// 合约编号
		cooperorgDealDTO.setAgreementCode(applyDto.getAgreementCode());// 协议编号
		cooperorgDealDTO.setDealDate(new java.util.Date());// 交易日期
		if (CimsConstant.COOPERORG_CODE_JY.equals(applyDto.getTransfereeCode())) {
			cooperorgDealDTO.setDealType(CimsConstant.DEAL_TYPE_CREDIT_IN);// 交易类型：债权受让
			cooperorgDealDTO.setCooperorgCode(applyDto.getTransferorCode());// 合作机构
		} else {
			cooperorgDealDTO.setDealType(CimsConstant.DEAL_TYPE_CREDIT_OUT);// 交易类型：债权转让
			cooperorgDealDTO.setCooperorgCode(applyDto.getTransfereeCode());// 合作机构
		}
		cooperorgDealDTO.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_CREATE);// 合作机构交易状态:01-新建
		cooperorgDealDTO.setCreateTime(new Timestamp(System.currentTimeMillis()));
		cooperorgDealDTO.setDealDate(new java.util.Date());
		UserInfo userInfo = sessionAPI.getCurrentUserInfo();
		if (userInfo != null) {
			cooperorgDealDTO.setCreateBy(userInfo.getUserId().toString());
			cooperorgDealDTO.setModifyBy(userInfo.getUserId().toString());
		}
		cooperorgDealDTO.setModifyTime(new Timestamp(System.currentTimeMillis()));
		cooperorgDealDTO.setBillDate(applyDto.getBillDate());// 账单日
		cooperorgDealDTO.setCreditPackageName(applyDto.getPackageNum());// 债权包名称
		cooperorgDealDTO.setInterfaceStatus(CimsConstant.INTERFACE_STATUS_NEW);
		cooperorgDealDTO.setBillDate(applyDto.getStatementDateStart());
		cooperorgDealDTO.setBillDateEnd(applyDto.getStatementDateEnd());
		cooperorgDealService.insertTCMmCooperorgDeal(cooperorgDealDTO);

		// 新增债权债权包
		TCMmCreditPackageDTO creditPackageDTO = new TCMmCreditPackageDTO();
		creditPackageDTO.setCooperorgCode(cooperorgDealDTO.getCooperorgCode());
		creditPackageDTO.setContractCode(applyDto.getContractCode());
		creditPackageDTO.setCreditPackageName(applyDto.getPackageNum());
		creditPackageDTO.setBillDate(applyDto.getStatementDateStart());
		creditPackageDTO.setBillDateEnd(applyDto.getStatementDateEnd());
		creditPackageDTO.setCreateTime(new Timestamp(System.currentTimeMillis()));
		if (userInfo != null) {
			creditPackageDTO.setCreateBy(userInfo.getUserId().toString());
			creditPackageDTO.setModifyBy(userInfo.getUserId().toString());
		}
		creditPackage.insertCreditPackageNoCheck(creditPackageDTO);

		cooperorgDealDTO = null;
		creditPackageDTO = null;
	}

	/**
	 * @description 删除交易流水
	 * @param dealCode
	 *            交易流水号
	 */
	public void deleteCooperorgDeal(String dealCode) throws Exception {
		TCMmCooperorgDealDTO cooperorgDealDTO = new TCMmCooperorgDealDTO();
		cooperorgDealDTO.setDealCode(dealCode);// 交易流水号
		List<TCMmCooperorgDealDTO> cooperorgDealDTOList = cooperorgDealService.searchTCMmCooperorgDeal(SearchParamUtil
				.getSearchParam(cooperorgDealDTO));
		if (CollectionsUtils.isEmpty(cooperorgDealDTOList)) {
			return;
		}

		cooperorgDealService.deleteTCMmCooperorgDealByPrimaryKey(new BaseDTO(), cooperorgDealDTOList.get(0).getId().toString());

		cooperorgDealDTO = null;
	}

	/**
	 * @description deleteCreditDetail
	 * @param dealCode
	 *            交易流水号
	 */
	public void deleteCreditDetail(String dealCode) throws Exception {
		DealDto dealDto = new DealDto();
		dealDto.setDealCode(dealCode);
		
		// 删除客户信息
		creditRightDao.deleteCustInfoByDealCode(SearchParamUtil.getSearchParam(dealDto));
				
		// 删除结算计划
		creditRightDao.deleteCostPlanByDealCode(SearchParamUtil.getSearchParam(dealDto));
		
		// 删除还款计划
		creditRightDao.deleteRefundPlanByDealCode(SearchParamUtil.getSearchParam(dealDto));
		
		// 删除债权明细
		creditRightDao.deleteCreditDetailByDealCode(SearchParamUtil.getSearchParam(dealDto));
		
		// 删除债权明细流水
		creditRightDao.deleteCreditDealDetailByDealCode(SearchParamUtil.getSearchParam(dealDto));
		
		// 删除交易流水
		creditRightDao.deleteCooperorgDealByDealCode(SearchParamUtil.getSearchParam(dealDto));	
	}
	
	
	/**
	 * @description 确认结果
	 * @param applyDto
	 *            债权申请实体
	 * @param applyResultDto
	 *            债权申请结果实体
	 * @throws Exception
	 * @author shengzhoutao
	 * @date 2015-07-07
	 */
	public void confirmApplyResult(CreditApplyDto applyDto, CreditApplyResultDto applyResultDto) throws Exception {

		List<CreditDetailDto> creditDetailList = applyResultDto.getCreditDetailList();
		if (CollectionsUtils.isEmpty(creditDetailList)) {
			return;
		}

		String cooperorgCode = "";// 合作机构编号
		String creditSource = "";// 债权来源
		String creditorStatus = CimsConstant.CREDIT_STATUS_WAY;// 债权状态
		if (CimsConstant.COOPERORG_CODE_JY.equals(applyDto.getTransfereeCode())) {
			cooperorgCode = applyDto.getTransferorCode();
			creditSource = CimsConstant.CREDIT_SOURCE_REC;
		} else {
			cooperorgCode = applyDto.getTransfereeCode();
			creditSource = CimsConstant.CREDIT_SOURCE_CRE;
		}
		
		//获取包信息
		Map<String, Object> searchParams = new HashMap<String, Object>();
		TCMmCreditPackageDTO tCMmCreditPackageDTO = new TCMmCreditPackageDTO();
		tCMmCreditPackageDTO.setContractCode(applyDto.getContractCode());
		tCMmCreditPackageDTO.setCooperorgCode(cooperorgCode);
		tCMmCreditPackageDTO.setCreditPackageName(applyDto.getPackageNum());
    	searchParams.put("dto", tCMmCreditPackageDTO);
        List<TCMmCreditPackageDTO> list = creditPackageService.searchTCMmCreditPackage(searchParams);
        if(list.size()>0){
        	tCMmCreditPackageDTO = list.get(0);
        }
		// 填充债权明细的值，组装成新的债权明细列表
		List<CreditDetailDto> newCreditDetailList = new ArrayList<CreditDetailDto>();
		for (CreditDetailDto creditDetailDto : creditDetailList) {
			String transferId = getTransferId();
			creditDetailDto.setTransferId(transferId);// 债权转让编号
			creditDetailDto.setCreditCode(transferId);// 债权编号
			creditDetailDto.setCooperorgCode(cooperorgCode);// 合作机构编号
			creditDetailDto.setContractCode(applyDto.getContractCode());// 合约编号
			creditDetailDto.setAgreementCode(applyDto.getAgreementCode());// 协议编号
			creditDetailDto.setPackageNum(applyDto.getPackageNum());// 债权包
			creditDetailDto.setCreditSource(creditSource);// 债权来源
			creditDetailDto.setCreditorStatus(creditorStatus);// 债权状态
			//creditDetailDto.setBillDate(creditDetailDto.getBillDate());// 账单日
			creditDetailDto.setCardType(creditDetailDto.getCardType() == null ? "1" : creditDetailDto.getCardType());
			creditDetailDto.setCustName(creditDetailDto.getBorrowerName());// 客户名称
			creditDetailDto.setCardId(creditDetailDto.getBorrowerIdNumber());// 证件号码
			creditDetailDto.setMonthlyRate(creditDetailDto.getLoanMonthlyinterest());// 月利率
			String productType = CQuotaImpl.getProdNameToprodType(creditDetailDto.getLoanProductName());//根据产品名称转换编码
			creditDetailDto.setProductType(productType);// 产品类型
			if (null == creditDetailDto.getDeliverDate()) {
				creditDetailDto.setDeliverDate(getDeliverDateForBillDate(String.valueOf(applyDto.getBillDate())));
			}
			creditDetailDto.setInitialCreditorValue(creditDetailDto.getMakeCreditorValue());
			
			if(null != tCMmCreditPackageDTO.getPlanRedeemDate()){
				creditDetailDto.setPlanRedeemDate(tCMmCreditPackageDTO.getPlanRedeemDate());//计划赎回日期
			}else{
				creditDetailDto.setPlanRedeemDate(null);
			}
			
			// 新增客户信息。
			createCustomer(applyDto.getDealCode(), creditDetailDto);

			newCreditDetailList.add(creditDetailDto);
		}
		// 重新赋值，以便下一个方法调用使用。
		applyResultDto.setCreditDetailList(newCreditDetailList);

		// 组装债权流水和债权明细数据
		List<TCMmCreditDealDetailDTO> creditDealDetailDTOList = new ArrayList<TCMmCreditDealDetailDTO>();
		List<TCMmCreditDetailDTO> creditDetailDTOList = new ArrayList<TCMmCreditDetailDTO>();
		TCMmCreditDealDetailDTO cdddto = null;
		TCMmCreditDetailDTO cddto = null;
		BigDecimal sumCreditorValue = new BigDecimal(0);
		
		for (CreditDetailDto creditDetailDto : newCreditDetailList) {
			cdddto = new TCMmCreditDealDetailDTO();
			cdddto.setDealStreamCode(applyDto.getDealCode());// 交易编号
			cdddto.setCooperorgCode(creditDetailDto.getCooperorgCode());// 合作机构编号
			cdddto.setAgreementCode(creditDetailDto.getAgreementCode());// 协议编号
			cdddto.setTransferId(creditDetailDto.getTransferId());// 转让编号
			cdddto.setCreditorId(creditDetailDto.getCreditCode());//
			cdddto.setDealSerial(1L);// 交易序号
			creditDealDetailDTOList.add(cdddto);

			cddto = new TCMmCreditDetailDTO();
			SimpleBeanUtils.copyBean2Bean(cddto, creditDetailDto);
			cddto.setId(null);
			cddto.setCreditSource(creditSource);
			cddto.setCreditorStatus(creditorStatus);
			cddto.setCreditorValueUpdateDate(new Date());
			creditDetailDTOList.add(cddto);

			sumCreditorValue = sumCreditorValue.add(creditDetailDto.getMakeCreditorValue());
		}

		// 批量新增债权流水
		creditRight.insertCreditDealDetailByBatch(creditDealDetailDTOList);
		// 批量新增债权明细
		creditRight.insertCreditDetailByBatch(creditDetailDTOList);

		// 更新债权明细，债权价值合计
		TCMmCooperorgDealDTO cooperorgDeal = new TCMmCooperorgDealDTO();
		cooperorgDeal.setDealCode(applyDto.getDealCode());
		List<TCMmCooperorgDealDTO> cooperorgDealList = cooperorgDealService.searchTCMmCooperorgDeal(SearchParamUtil.getSearchParam(cooperorgDeal));
		cooperorgDeal = cooperorgDealList.get(0);
		cooperorgDeal.setDetialNumber(creditDetailDTOList.size());
		cooperorgDeal.setSumCreditorValue(sumCreditorValue);
		cooperorgDealService.updateTCMmCooperorgDeal(cooperorgDeal);

		cooperorgDeal = null;
		cdddto = null;
		cddto = null;
		newCreditDetailList = null;
		creditDealDetailDTOList = null;
		creditDetailDTOList = null;
	}
	@Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 5)
	private String getTransferId(){
		return csysAssistimpl.getBizNo(CimsConstant.BIZNO_TYPE_CRSR);
	}
	
	/**
	 * @description 新增客户信息。
	 * @param dealCode
	 *            交易流水号
	 * @param creditDetailDto
	 *            债权明细
	 * @throws Exception
	 */
	private void createCustomer(String dealCode, CreditDetailDto creditDetailDto) throws Exception {
		CustomerDto customerDto = new CustomerDto();
		customerDto.setCardType(Integer.parseInt(creditDetailDto.getCardType()));
		customerDto.setCardNumber(creditDetailDto.getCardId());
		// 调用接口验证客户信息是否存在
		JResult result = cIRBaseDataSysImpl.validateCustomer(customerDto);
		if (!result.isSuccess()) {
			throw new Exception("验证客户信息出错！");
		}
		Map<String, Object> map = null;
		String errCode = result.getErrCode();
		// 如果验证客户信息，客户信息不存在，需要调用接口新增客户信息
		if (STATUS_NONENTITY.equals(errCode)) {
			customerDto = new CustomerDto();
			customerDto.setCardType(Integer.parseInt(creditDetailDto.getCardType()));
			customerDto.setCardNumber(creditDetailDto.getCardId());
			UserInfo userInfo = sessionAPI.getCurrentUserInfo();
			if (null != userInfo) {
				customerDto.setCreator(userInfo.getUserId().toString());// 设置创建人的值
			}

			// 调用接口新增客户信息
			customerDto.setName(creditDetailDto.getCustName());
			customerDto.setInitSystem(SYS_CODE_CIMS);
			result = cIRBaseDataSysImpl.createOrupdateCustomer(customerDto);

			if (!result.isSuccess()) {
				throw new Exception("新增客户信息出错！");
			}
			errCode = result.getErrCode();
			if (!STATUS_SUCCESS.equals(errCode)) {// 如果新增客户不成功，直接报错。
				throw new Exception("新增客户信息异常:" + result.getErrMsg());
			}
			// 新增成功需要返回客户编码，如果不能获取客户编码直接报错
			map = result.getMap();
			if (null == map) {
				throw new Exception("新增客户信息异常:" + result.getErrMsg());
			}
			if (null == map.get(CUST_CODE_KEY_NAME)) {
				throw new Exception("新增客户信息异常:" + result.getErrMsg());
			}
		} else {
			// 如果返回信息不是成功状态，需要抛出异常。
			if (!STATUS_SUCCESS.equals(errCode)) {
				throw new Exception("验证客户信息异常:" + result.getErrMsg());
			}
			// 返回成功状态,客户信息已经存在，需要返回客户编码，，如果不能获取客户编码直接报错
			map = result.getMap();
			if (null == map) {
				throw new Exception("验证客户信息异常:" + result.getErrMsg());
			}
			if (null == map.get(CUST_CODE_KEY_NAME)) {
				throw new Exception("验证客户信息异常:" + result.getErrMsg());
			}
		}

		// 获取返回客户信息编码
		String custCode = (String) map.get(CUST_CODE_KEY_NAME);
		// 设置返回客户编码(重要)，下一个方法需要。
		creditDetailDto.setLoanUserId(custCode);// 客户编号
		creditDetailDto.setCustCode(custCode);// 客户编号

		// 保存本地数据库的客户信息
		insertTCMmCustinfo(creditDetailDto.getCardType(), creditDetailDto.getCardId(), dealCode, creditDetailDto.getTransferId(), custCode,
				creditDetailDto.getCustName());

		customerDto = null;
	}

	// 保存本地数据库的客户信息
	private long insertTCMmCustinfo(final String cardType, final String cardId, final String quotaCode, final String fromCode, final String custCode,
			final String custName) throws Exception {
		TCMmCustinfoDTO custinfo = new TCMmCustinfoDTO();
		// 填充值
		custinfo.setCardType(cardType);
		custinfo.setCardId(cardId);
		custinfo.setQuotaCode(quotaCode);
		custinfo.setFromType(CimsConstant.QUOTATYPE_CR);
		custinfo.setFromCode(fromCode);
		custinfo.setCustCode(custCode);
		custinfo.setCustName(custName);

		// 保存本地数据库的客户信息
		return tCMmCustinfoService.insertTCMmCustinfo(custinfo);
	}

	/**
	 * @description 根据账单日生成交割日期
	 * @param billDate
	 *            账单日
	 * @return Date 交割日期
	 */
	private Date getDeliverDateForBillDate(final String billDate) {
		Date promptyDate = null;
		int curDay = Calendar.getInstance().get(Calendar.DATE);
		Date date = new Date();
		if (CimsConstant.SETTLE_DAY_1.equals(billDate)) {
			promptyDate = DateTimeUtils.getMonthFirstDay(date);
		} else {
			if (curDay == Integer.parseInt(billDate)) {
				promptyDate = date;
			} else if (curDay < Integer.parseInt(billDate)) {
				String dateStr = DateTimeUtils.formatDate(date, DateTimeUtils.DEFAULT_DATE_FORMAT);
				promptyDate = DateTimeUtils.parse(dateStr.substring(0, 6) + billDate, DateTimeUtils.DEFAULT_DATE_FORMAT);
				promptyDate = DateTimeUtils.addMonths(promptyDate, -1);
			} else {
				String dateStr = DateTimeUtils.formatDate(date, DateTimeUtils.DEFAULT_DATE_FORMAT);
				promptyDate = DateTimeUtils.parse(dateStr.substring(0, 6) + billDate, DateTimeUtils.DEFAULT_DATE_FORMAT);
			}
		}
		return promptyDate;
	}
}
